#ifndef LOG_H
#define LOG_H

#include <mutex>
#include "blockqueue.h"
#include <sys/time.h>
#include <memory>
#include <stdarg.h>
#include <thread>
#include <sys/stat.h>

class Log {
public:
    static Log* Instance();

    void Init(int level, const char* path = "./log", const char* suffix = ".log", 
    int maxdequecapacity = 1024);

    static void FlushLogThread();

    bool IsOpen() {return m_isOpen;};

    int GetLevel();

    void Write(int level, const char* format, ...);

    void Flush(); // 更新缓冲区，防止多线程时数据冲刷，通知写入线程notifyone

private:
    void AsyncWrite(); // 与write不同的是write是加入阻塞队列，asyncwrite是从阻塞队列中取出进行写操作   
    
    Log();

    virtual ~Log();
private:
    static const int MAX_LINES = 50000;
    static const int LOG_NAME_LEN = 256;
    static const int LOG_PATH_LEN = 256;

    const char* m_path; // log文件夹的路径
    const char* m_suffix; // 后缀

 

    FILE * m_fp;

    int m_lineCount; // 文件行数
    bool m_isOpen;
    int m_level; // 日志等级
    bool m_isAsync; // 是否异步
    std::mutex mtx;
    int m_today; // 今天的日期

    std::unique_ptr<BlockDeque<std::string>> m_deque; // 日志阻塞队列
    std::unique_ptr<std::thread> m_writeThread;
};

#define LOG_BASE(level, format, ...) \
    do {\
        Log* log = Log::Instance(); \
        if (log->IsOpen() && log->GetLevel() <= level) {\
            log->Write(level, format, ##__VA_ARGS__);\
            log->Flush();\
        }\
    } while(0);


// 日志四个级别，debug,info,warn,error
#define LOG_DEBUG(format, ...) do {LOG_BASE(0, format, ##__VA_ARGS__)} while(0);
#define LOG_INFO(format, ...) do {LOG_BASE(1, format, ##__VA_ARGS__)} while(0);
#define LOG_WARN(format, ...) do {LOG_BASE(2, format, ##__VA_ARGS__)} while(0);
#define LOG_ERROR(format, ...) do {LOG_BASE(3, format, ##__VA_ARGS__)} while(0);


#endif